The Matching Functions - :samp:`compare`
===============================================

The index matching algorithm used by Crystal Ball Plus lies in the ``compare`` module. 

What the program does is:

#. Comparing the *d-spacings*
#. Generating the *d-spacings* report.
#. Grouping the matching reflections
#. Comparing the *angles*
#. Generating the *angles* report

Each operation can be performed automatically using the ``crystalballplus`` executable via the graphical or the text interface (see :doc:`../quickstart`), or can be performed by hand within any Python shell as e.g. `IPython <http://ipython.org/>`_.

In the first step, the input and reference files are read and the results are output in a Python *dictionary of dictionaries* that has the same structure of a file system: the keys of the first dictionary represent the input files, the keys of the second dictionary (which are in fact the *values* of the first dictionary) represent the reference files and, finally, the values of the second dictionary represent the results of the matching algorithm.

For example, here is a way to represent a *dictionary of dictionaries* obtained when analyzing two input and two reference files::

   INPUT_01
          |
	  |---REF_01 : result01
	  |
	  |---REF_02 : result02

   INPUT_02
          |
	  |---REF_01 : result03
	  |
	  |---REF_02 : result04

This structure allows one to treat multiple input and reference files at the same time without losing information.

.. automodule:: crystalballplus.compare

Comparing the *d-spacings*
---------------------------

The first step is to compare the *d-spacings*. This is done using the function ``compare.compare_d``:

.. autofunction:: compare_d

For example:

   >>> D = compare.compare_d('path/to/input.dfg', 'path/to/ref.dfg')

will create a dictionary containing the possible *d-spacing* matches between **input.dfg** and **ref.dfg**.

.. note::
   The same *d-spacing* may match more than one reflection of the reference structure. **All** the matching reflections will be loaded into the output dictionary.

Grouping the reflections
-------------------------

Once the *d-spacings* have been matched, it is necessary to group them in pairs.  This is accomplished by feeding the result of ``compare_d`` to ``compare.group_reflections``:

.. autofunction:: group_reflections

.. note::

    The reflections are grouped in at most **three pairs**. So, if our input file contained two reflections R0 and R1, we would have: (R0, R1). If we added a third reflection R2, we would have: (R0, R1), (R1, R2), (R0, R2).

Comparing the *angles*
-----------------------
Once all the reflections are grouped in pairs, the angle between each pair can be calculated and matched against the reference structure using ``compare.compare_angles``:

.. autofunction:: compare_angles